from duckserver.models import Work, User
from duckserver.models import Follow
from duckserver.models import Grouprelation
import datetime

# 计算关注用户的分数
# 发贴人为关注用户则100分，不是关注用户则记0分
# userid:当前用户id，postuserid:发贴人id
from duckserver.service.work import getWorkInfo


def getFollowMark(userid, postuserid):
    record = Follow.objects.filter(userid=postuserid, follower=userid)
    if len(record) == 0:
        return 0
    else:
        return 100


# 计算关注圈子对用户的影响权重
# 贴子为用户关注的圈子则100分，不是关注用户则记0分
# userid:当前用户id，groupid:贴子所在圈子的id
def getGroupMark(userid, groupid):
    record = Grouprelation.objects.filter(userid=userid, groupid=groupid)
    if len(record) == 0:
        return 0
    else:
        return 100


# 计算贴子热度对用户的影响权重
# attitudeNum:点赞数量, commentNum:评论的数量
def getHeatMark(attitudeNum, commentNum):
    attitudeMark = 0
    commentMark = 0
    # 点赞的评分机制如下:[10赞内0-25,100赞内10-100,500赞内50-75,1000赞内75-100，大于1000赞满分]
    if attitudeNum <= 10:
        attitudeMark = attitudeNum / 10 * 25
    elif attitudeNum <= 100:
        attitudeMark = (attitudeNum - 10) / 90 * 25 + 25
    elif attitudeNum <= 500:
        attitudeMark = (attitudeNum - 100) / 400 * 25 + 75
    elif attitudeNum <= 1000:
        attitudeMark = (attitudeNum - 500) /500 * 25 + 75
    else:
        attitudeMark = 100
    # 评论的评分机制如下[10回复内0-50,50回复内50-100,大于50回复满分]
    if commentNum <= 10:
        commentMark = commentNum / 10 * 50
    elif commentNum <= 50:
        commentMark = (commentNum - 10) / 40 * 50 + 50
    else:
        commentMark = 100
    # 贴子热度的评判: 70%点赞+30%评论
    return 0.7 * attitudeMark + 0.3 * commentMark


# 计算贴子收费对用户的影响权重
# getPaid: 获得贴子需要的鸭蛋数量
def getPaidMark(getPaid):
    if getPaid <= 10:
        return getPaid / 10 * 100
    else:
        return 0


# 计算标签对用户的影响权重
def getTagMark():
    ##################################
    # 我不会啊啊啊啊啊啊啊啊爸爸们救命救命 #
    ##################################
    return 100


# 计算贴子发布时间给贴子带来的评分
# 评分机制如下:[1小时内100,今天内80-100,3天内60-80,
# 1周内40-60,1月内20-40,3月内0-20,更久0分]
# 各个分数段中是个均匀分布
# releaseTime:贴子的发布时间
def getTimeMark(releaseTime):
    now_day = datetime.datetime.now().date()
    release_day = datetime.datetime.fromtimestamp(releaseTime)
    difference = now_day - release_day
    # 先根据天数进行判断:当天的贴子 80-100
    if difference.days < 1:
        hours = difference.seconds // 3600
        return (24 - hours) / 24 * 20 + 80
    # 非当天的贴子,但三天内的贴子 60-80
    elif difference.days <= 3:
        hours = difference.seconds // 3600 - 24
        return (48 - hours) / 48 * 20 + 60
    # 非三天内的贴子，一周内的贴子 40-60
    elif difference.days <= 7:
        return (7 - difference.days) / 4 * 20 + 40
    # 非一周内的贴子，一个月内的贴子 20-40
    elif difference.days <= 30:
        return (30 - difference.days) / 23 * 20 + 20
    elif difference.days <= 90:
        return (90 - difference.days) / 60 * 20
    # 超过三个月的贴子 0分
    else:
        return 0


# 辅助函数:长度为n的list1和list2保持下标一一对应关系
# 对list2进行从小到大排序
def sortList2(list1, list2, n):
    # 插入排序，同时变动list1的值使得下表一致
    for i in range(1, n):
        key2 = list2[i]
        key1 = list1[i]
        j = i - 1
        while j >= 0 and key2 < list2[j]:
            list2[j + 1] = list2[j]
            list1[j + 1] = list1[j]
            j -= 1
        list2[j + 1] = key2
        list1[j + 1] = key1


# 当用户在推荐界面喜欢一个贴子后的反馈调整函数
# 根据用户行为调整权重
# userid: 点赞人用户id，workid: 被点赞的贴子
def feedback(userid, workid):
    response = {'ok': 0, 'msg': ''}
    # 获取这个用户的权重
    user = User.objects.get(userid=userid)
    work = Work.objects.get(workid=workid)
    # 计算这个贴子的影响权重
    follow_mark = getFollowMark(userid, work.userid.userid)
    group_mark = getGroupMark(userid, work.groupid.groupid)
    heat_mark = getHeatMark(work.attitudenum, work.commentnum)
    paid_mark = getPaidMark(work.getpaid)
    tag_mark = getTagMark()
    mark = follow_mark + group_mark + heat_mark + paid_mark + tag_mark

    # 新权重:90%旧权重+10%新权重
    user.followweight = user.followweight * 0.9 + follow_mark / mark * 0.1
    user.groupweight = user.groupweight * 0.9 + group_mark /mark * 0.1
    user.heatweight = user.heatweight * 0.9 + heat_mark / mark * 0.1
    user.paidweight = user.paidweight * 0.9 + paid_mark / mark * 0.1
    user.tagweight = user.tagweight * 0.9 + tag_mark / mark * 0.1

    response['ok'] = 1
    response['msg'] = '调整权值成功'
    # 更新
    user.save()
    return response